/**
 * 应用版本更新服务
 * 基于AppVersionApi.getAppVersionPage接口，完全重写UI和后续逻辑
 * 支持强制更新、静默更新、下载进度显示等功能
 * 遵循APP版本更新功能开发说明书规范
 */

// #ifdef APP-PLUS

import { AppVersionApi } from "@/api/system/appversion";
import config from "@/config";

// 获取全局modal实例的辅助函数
function getGlobalModal() {
  // 尝试获取全局的$modal实例
  const app = getApp();
  if (app && app.$modal) {
    return app.$modal;
  }

  // 尝试通过uni对象获取
  if (uni.$modal) {
    return uni.$modal;
  }

  // 如果都找不到，返回null
  return null;
}

const PACKAGE_INFO_KEY = "__app_update_info__";

/**
 * 版本号比较（简化版 - 直接整数比较）
 * @param {string|number} v1 - 版本号1
 * @param {string|number} v2 - 版本号2
 * @returns {number} 1: v1>v2, -1: v1<v2, 0: v1=v2
 */
function compareVersions(v1, v2) {
  // 直接转换为整数比较大小
  const num1 = parseInt(v1) || 0;
  const num2 = parseInt(v2) || 0;

  if (num1 > num2) return 1;
  if (num1 < num2) return -1;
  return 0;
}

/**
 * 申请安装权限（Android 12+ 需要"来自此来源"授权）
 * 通用写法（12/13/14 也走这条）
 * @returns {Promise<boolean>} 是否获得权限
 */
async function reqInstallPermission() {
  const can = plus.android.invoke(pm, "canRequestPackageInstalls");
  console.log(">>> MuMu 安装权限检查结果:", can);
  // ====== 调试开关：MuMu/本地跳过权限检查 ======
  const isMuMu = uni.getSystemInfoSync().deviceModel.includes("MuMu");
  const isDebug = true; // 你手动控制调试状态

  if (isMuMu || isDebug) {
    console.warn(">>> 调试模式：跳过安装权限检查");
    return true;
  }
  // ============================================

  // #ifdef APP-PLUS
  if (uni.getSystemInfoSync().platform !== "android") return true;

  const main = plus.android.runtimeMainActivity();
  const pm = plus.android.invoke(main, "getPackageManager");

  // 8.0+ 统一用 canRequestPackageInstalls()
  const canInstall = plus.android.invoke(pm, "canRequestPackageInstalls");
  if (!canInstall) {
    const Intent = plus.android.importClass("android.content.Intent");
    const Uri = plus.android.importClass("android.net.Uri");
    main.startActivity(
      new Intent(
        "android.settings.MANAGE_UNKNOWN_APP_SOURCES",
        Uri.parse("package:" + plus.runtime.appid)
      )
    );

    // 用户返回后再检查一次
    return new Promise((resolve) => {
      const listener = () => {
        plus.globalEvent.removeEventListener("resume", listener);
        setTimeout(() => {
          resolve(plus.android.invoke(pm, "canRequestPackageInstalls"));
        }, 1000);
      };
      plus.globalEvent.addEventListener("resume", listener, false);
      setTimeout(() => {
        plus.globalEvent.removeEventListener("resume", listener);
        resolve(false);
      }, 30000);
    });
  }
  return true;
  // #endif
}

/**
 * 显示下载进度弹窗
 * @param {Object} updateInfo - 更新信息
 * @param {function} onCancel - 取消回调
 * @returns {Object} 弹窗控制对象
 */
function showDownloadDialog(updateInfo, onCancel) {
  const { title, pkg_size } = updateInfo;

  return {
    close: () => {
      uni.hideLoading();
    },
    updateProgress: (progress) => {
      // uni.showLoading({
      //   title: `下载中 ${progress}%...`,
      //   mask: true,
      // });
    },
  };
}

/**
 * 安装包
 * @param {string} filePath - 安装包路径
 * @param {Object} updateInfo - 更新信息
 * @param {Object} options - 配置选项
 * @returns {Promise<void>}
 */
async function installPackage(filePath, updateInfo, options = {}) {
  console.log("=== 真机诊断开始 ===");
  console.log(">>> 文件路径:", filePath);
  // console.log(">>> authority:", authority);
  // 安装前再打印一次
  console.log(">>> 安装层使用 installPath：" + JSON.stringify(filePath));

  console.log("====== MuMu 安装前检查开始 ======");
  console.log(">>> 下载成功，filePath:", filePath, "statusCode:", 200);
  // 0. 平台校验
  if (uni.getSystemInfoSync().platform !== "android") {
    console.log("❌ 非 Android 平台，中断");
    throw new Error("仅支持 Android 平台安装");
  }
  console.log("✅ 0. 平台校验通过");

  // 1. 文件是否存在（下载完成）
  console.log(">>> 开始文件系统解析，filePath:", filePath);

  // 使用 Promise 包装回调方式
  const resolveFileEntry = () => {
    return new Promise((resolve, reject) => {
      plus.io.resolveLocalFileSystemURL(
        filePath,
        (entry) => {
          console.log(">>> 文件系统解析成功:", entry);
          console.log(">>> entry.toLocalURL:", entry.toLocalURL());
          resolve(entry);
        },
        (error) => {
          console.error(">>> 文件系统解析失败:", error);
          reject(new Error(`文件系统解析失败: ${error.message}`));
        }
      );
    });
  };

  let entry;
  let file;
  try {
    entry = await resolveFileEntry();

    if (!entry || !entry.toLocalURL) {
      throw new Error("文件系统解析返回无效对象");
    }

    const File = plus.android.importClass("java.io.File");
    const localUrl = entry.toLocalURL();
    console.log(">>> 原始localUrl:", localUrl);

    if (!localUrl) {
      throw new Error("无法获取文件本地URL");
    }

    // 更完善的路径处理
    let filePath = localUrl;
    if (filePath.startsWith("file://")) {
      filePath = filePath.substring(7); // 移除file://前缀
    }
    console.log(">>> 处理后的文件路径:", filePath);

    file = plus.android.newObject("java.io.File", filePath);
    console.log(">>> File对象创建:", file ? "成功" : "失败");

    // ===== 真机诊断开始 =====
    console.log("=== 真机诊断开始 ===");

    // ① 文件存在性检查
    try {
      const fileExists = plus.android.invoke(file, "exists");
      const canRead = plus.android.invoke(file, "canRead");
      const fileSize = plus.android.invoke(file, "length");
      console.log(
        ">>> 文件存在:",
        fileExists,
        "可读:",
        canRead,
        "大小:",
        fileSize,
        "字节"
      );

      if (!fileExists) {
        console.error(">>> ❌ 文件不存在，无法继续安装");
        throw new Error("文件不存在");
      }
      if (!canRead) {
        console.error(">>> ❌ 文件不可读，检查权限");
        throw new Error("文件不可读");
      }
    } catch (e) {
      console.error(">>> 文件检查失败:", e.message);
      throw new Error(`文件检查失败: ${e.message}`);
    }

    // ② 安装权限检查
    try {
      const pm = plus.android.invoke(
        plus.android.runtimeMainActivity(),
        "getPackageManager"
      );
      const canInstall = plus.android.invoke(pm, "canRequestPackageInstalls");
      console.log(">>> 安装权限状态:", canInstall ? "已授权" : "未授权");

      if (!canInstall) {
        console.warn(">>> ⚠️ 缺少安装权限，将引导用户开启");
      }
    } catch (e) {
      console.error(">>> 权限检查失败:", e.message);
    }

    // ③ FileProvider可用性检查
    try {
      const FileProviderClass = plus.android.importClass(
        "androidx.core.content.FileProvider"
      );
      console.log(
        ">>> FileProvider类加载:",
        FileProviderClass ? "成功" : "失败"
      );

      // 获取authority
      // const authority = plus.runtime.appid + ".dc.fileprovider";
      const authority = "com.isteel.app.dc.fileprovider";
      console.log(">>> Authority:", authority);

      // 获取上下文
      const context = plus.android.runtimeMainActivity();
      console.log(">>> Context:", context ? "有效" : "null");

      // 尝试生成URI
      const testUri = FileProviderClass.getUriForFile(context, authority, file);
      console.log(">>> URI生成测试:", testUri ? "成功" : "失败");
      if (testUri) {
        console.log(">>> URI:", plus.android.invoke(testUri, "toString"));
      }
    } catch (e) {
      console.error(">>> FileProvider检查失败:", e.message);
      console.error(
        ">>> 建议检查: 1)AndroidManifest.xml配置 2)file_provider_paths.xml 3)authority匹配"
      );
    }

    // ④ Intent构建和验证
    try {
      const Intent = plus.android.importClass("android.content.Intent");
      const testIntent = new Intent(Intent.ACTION_VIEW);

      // 获取authority和URI
      //const authority = plus.runtime.appid + ".dc.fileprovider";
      const authority = "com.isteel.app.dc.fileprovider";
      const FileProviderClass = plus.android.importClass(
        "androidx.core.content.FileProvider"
      );
      const context = plus.android.runtimeMainActivity();
      const testUri = FileProviderClass.getUriForFile(context, authority, file);

      testIntent.setDataAndType(
        testUri,
        "application/vnd.android.package-archive"
      );
      testIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      testIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

      console.log(">>> Intent构建:", "成功");

      // 检查是否有应用可以处理这个Intent
      const packageManager = plus.android.invoke(context, "getPackageManager");
      const activities = plus.android.invoke(
        packageManager,
        "queryIntentActivities",
        testIntent,
        0
      );
      console.log(
        ">>> 可处理安装的应用数:",
        activities ? plus.android.invoke(activities, "size") : 0
      );
    } catch (e) {
      console.error(">>> Intent构建失败:", e.message);
    }

    console.log("====== 真机诊断完成 ======");

    const exist = plus.android.invoke(file, "exists");
    console.log(">>> 文件存在检查:", exist);

    if (!exist) {
      throw new Error(`安装包文件不存在: ${filePath}`);
    }

    // 检查文件是否可读
    const canRead = plus.android.invoke(file, "canRead");
    console.log(">>> 文件可读检查:", canRead);

    if (!canRead) {
      console.warn(">>> 文件不可读，尝试获取文件信息:");
      try {
        const absolutePath = plus.android.invoke(file, "getAbsolutePath");
        console.log(">>> 绝对路径:", absolutePath);
        const parent = plus.android.invoke(file, "getParent");
        console.log(">>> 父目录:", parent);
        const parentFile = plus.android.invoke(file, "getParentFile");
        if (parentFile) {
          const parentExists = plus.android.invoke(parentFile, "exists");
          console.log(">>> 父目录存在:", parentExists);
          const parentCanRead = plus.android.invoke(parentFile, "canRead");
          console.log(">>> 父目录可读:", parentCanRead);
        }
      } catch (infoError) {
        console.error(">>> 获取文件信息失败:", infoError.message);
      }
    }

    console.log("✅ 1. 文件存在检查通过");
  } catch (fileError) {
    console.error("❌ 文件检查失败:", fileError.message);
    throw new Error(`安装包文件检查失败: ${fileError.message}`);
  }

  // 检查Android 12+安装权限（在FileProvider之前）
  const { silent = false } = options;
  const { is_mandatory, type } = updateInfo;

  try {
    // Android 12+ 需要先申请安装权限
    const hasInstallPermission = await reqInstallPermission();
    if (!hasInstallPermission) {
      const error = new Error("用户未授予安装权限，无法安装更新");
      console.error("安装权限申请失败");

      if (!options.silent) {
        uni.showModal({
          title: "❌ 安装权限未授予",
          content: '请在系统设置中开启"允许来自此来源"的安装权限，然后重试',
          showCancel: false,
          confirmText: "我知道了",
          confirmColor: "#ef4444",
        });
      }

      throw error;
    }

    console.log("安装权限检查通过");
  } catch (permissionError) {
    console.error("权限检查失败:", permissionError);
    throw permissionError;
  }

  // 2. FileProvider URI 生成
  let context;
  let uri;
  try {
    context = plus.android.runtimeMainActivity();
    //const authority = plus.runtime.appid + ".dc.fileprovider";
    const authority = "com.isteel.app.dc.fileprovider";
    console.log(">>> FileProvider Authority:", authority);
    console.log(">>> App ID:", plus.runtime.appid);
    console.log(">>> Context:", context ? "有效" : "null");
    console.log(">>> File object:", file ? "有效" : "null");

    // 获取文件绝对路径用于调试
    try {
      const absolutePath = plus.android.invoke(file, "getAbsolutePath");
      console.log(">>> 文件绝对路径:", absolutePath);

      // 检查是否在外部存储
      const Environment = plus.android.importClass("android.os.Environment");
      const externalStorageState = Environment.getExternalStorageState();
      console.log(">>> 外部存储状态:", externalStorageState);

      if (Environment.MEDIA_MOUNTED === externalStorageState) {
        const externalStorageDir = Environment.getExternalStorageDirectory();
        console.log(
          ">>> 外部存储目录:",
          externalStorageDir ? externalStorageDir.toString() : "null"
        );
      }
    } catch (pathError) {
      console.warn(">>> 获取文件路径信息失败:", pathError.message);
    }

    const FileProvider = plus.android.importClass(
      "androidx.core.content.FileProvider"
    );
    console.log(
      ">>> FileProvider class:",
      FileProvider ? "已导入" : "导入失败"
    );
    console.log(">>> 入参检查");
    console.log(">>> context:", context);
    console.log(">>> authority:", authority);
    console.log(">>> file   :", file);

    uri = FileProvider.getUriForFile(context, authority, file);
    console.log(">>> getUriForFile result:", uri ? "成功" : "null");
    console.log(">>> URI11111:", uri ? uri.toString() : "null");

    if (!uri) {
      throw new Error(
        ">>> FileProvider.getUriForFile 返回 null - 请检查: 1) AndroidManifest.xml中的FileProvider配置 2) file_provider_paths.xml路径配置 3) authority是否匹配 4) 文件路径是否在允许的paths中"
      );
    }

    console.log("✅ 2. FileProvider URI:", uri.toString());
  } catch (uriError) {
    console.error("❌ FileProvider URI 生成失败:", uriError.message);
    console.error(">>> FileProvider11111 内部异常:", e.message, e.stack);
    throw new Error(`FileProvider URI 生成失败: ${uriError.message}`);
  }

  // 3. Intent 拼装
  let intent;
  try {
    const Intent = plus.android.importClass("android.content.Intent");
    intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "application/vnd.android.package-archive");
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    console.log("✅ 3. Intent 拼装完成");
  } catch (intentError) {
    console.error("❌ Intent 拼装失败:", intentError.message);
    throw new Error(`Intent 拼装失败: ${intentError.message}`);
  }

  // 4. 双份 URI 授权（MuMu 也必需）
  try {
    const Intent = plus.android.importClass("android.content.Intent");
    const PackageManager = plus.android.importClass(
      "android.content.pm.PackageManager"
    );

    // 获取PackageManager实例
    const packageManager = plus.android.invoke(context, "getPackageManager");
    console.log(
      ">>> PackageManager实例:",
      packageManager ? "获取成功" : "获取失败"
    );

    if (!packageManager) {
      console.warn("⚠️ 无法获取PackageManager，跳过URI授权步骤");
    } else {
      // 查询能够处理安装Intent的Activity
      const resInfo = plus.android.invoke(
        packageManager,
        "queryIntentActivities",
        intent,
        0
      );
      console.log(
        ">>> queryIntentActivities结果:",
        resInfo ? "获取成功" : "获取失败"
      );

      if (resInfo && plus.android.invoke(resInfo, "size") > 0) {
        const size = plus.android.invoke(resInfo, "size");
        console.log(">>> 找到的Activity数量:", size);

        for (let i = 0; i < size; i++) {
          const resolveInfo = plus.android.invoke(resInfo, "get", i);
          console.log(">>> resolveInfo类型:", typeof resolveInfo);
          console.log(">>> resolveInfo:", resolveInfo);

          // 对于JSBObject，尝试使用plus.android.getAttribute来获取属性
          let activityInfo;
          try {
            // 尝试使用getAttribute方法获取activityInfo
            activityInfo = plus.android.getAttribute(
              resolveInfo,
              "activityInfo"
            );
            console.log(">>> 使用getAttribute获取activityInfo:", activityInfo);
          } catch (e) {
            console.warn(">>> getAttribute获取activityInfo失败:", e.message);

            // 尝试使用invoke方法调用getter
            try {
              activityInfo = plus.android.invoke(
                resolveInfo,
                "getActivityInfo"
              );
              console.log(
                ">>> 使用getActivityInfo获取activityInfo:",
                activityInfo
              );
            } catch (e2) {
              console.warn(">>> getActivityInfo失败:", e2.message);

              // 最后尝试直接访问属性
              try {
                activityInfo = resolveInfo.activityInfo;
                console.log(">>> 直接访问activityInfo:", activityInfo);
              } catch (e3) {
                console.warn(">>> 直接访问activityInfo失败:", e3.message);
                continue;
              }
            }
          }

          if (!activityInfo) {
            console.warn(">>> 无法获取activityInfo，跳过此条目");
            continue;
          }

          // 尝试不同的方式获取packageName
          let packageName;
          try {
            // 优先使用getAttribute获取packageName
            packageName = plus.android.getAttribute(
              activityInfo,
              "packageName"
            );
            console.log(">>> 使用getAttribute获取packageName:", packageName);
          } catch (e) {
            console.warn(">>> getAttribute获取packageName失败:", e.message);

            try {
              // 尝试使用invoke方法
              packageName = plus.android.invoke(activityInfo, "getPackageName");
              console.log(
                ">>> 使用getPackageName获取packageName:",
                packageName
              );
            } catch (e2) {
              console.warn(">>> getPackageName失败:", e2.message);

              try {
                packageName = activityInfo.packageName;
                console.log(">>> 直接访问packageName:", packageName);
              } catch (e3) {
                console.warn(">>> 直接访问packageName失败:", e3.message);
                continue;
              }
            }
          }

          console.log(">>> 最终授权包名:", packageName);

          if (packageName) {
            // 授予URI权限
            plus.android.invoke(
              context,
              "grantUriPermission",
              packageName,
              uri,
              plus.android.invoke(Intent, "FLAG_GRANT_READ_URI_PERMISSION")
            );
            console.log("④ 已授权包:", packageName);
          } else {
            console.warn(">>> packageName为null，跳过授权");
          }
        }
      } else {
        console.log(">>> 未找到能够处理安装Intent的Activity");
      }
    }
    console.log("✅ 4. URI 授权完成");
  } catch (grantError) {
    console.warn("⚠️ URI 授权失败:", grantError.message);
    console.warn("⚠️ URI 授权失败详情:", grantError.stack);
    // URI 授权失败不中断安装，只是警告
  }

  // 5. 启动安装Intent
  console.log("✅ 5. 即将发出安装 Intent");
  try {
    context.startActivity(intent);
    console.log("✅ 安装 Intent 已发出，等待系统安装器弹出...");
  } catch (e) {
    console.error("❌ 启动安装器失败:", e.message);
    throw new Error(`启动安装器失败: ${e.message}`);
  }

  // 6. 监听安装完成（仅适用于强制更新或wgt更新）
  if (updateInfo.is_mandatory || updateInfo.type === "wgt") {
    try {
      // 监听安装完成
      const onNewIntent = () => {
        console.log("安装界面返回，检查安装状态");
        plus.android
          .runtimeMainActivity()
          .removeEventListener("newintent", onNewIntent);

        // 安装完成后重启应用
        console.log("安装完成，准备重启应用...");
        setTimeout(() => {
          plus.runtime.restart();
        }, 1000); // 延迟1秒重启，确保安装完成
      };

      plus.android
        .runtimeMainActivity()
        .addEventListener("newintent", onNewIntent);

      console.log("已添加安装完成监听器");
    } catch (listenError) {
      console.warn("添加安装监听器失败:", listenError.message);
      // 监听失败不影响安装流程
    }
  }

  // 安装流程完成，等待系统安装器处理
  console.log("✅ 安装流程完成，等待系统安装器处理...");

  // 非静默模式显示安装提示
  if (!options.silent) {
    uni.showModal({
      title: "🔄 安装进行中",
      content: "系统安装器已启动，请完成安装操作",
      showCancel: false,
      confirmText: "我知道了",
      confirmColor: "#10b981",
    });
  }
  console.log("====== 安装流程完成 ======");
}

/**
 * 询问用户是否安装
 * @param {string} filePath - 安装包路径
 * @param {Object} updateInfo - 更新信息
 * @returns {Promise<void>}
 */
async function askForInstall(filePath, updateInfo) {
  return new Promise(async (resolve) => {
    uni.hideLoading();

    // 根据用户之前的选项直接处理，不再询问确认
    console.log("下载完成，直接开始安装，不再询问用户确认");

    // 直接开始安装，不再显示安装确认弹窗
    try {
      await installPackage(filePath, updateInfo);
      resolve();
    } catch (error) {
      console.error("安装失败:", error);
      resolve(); // 安装失败也算完成
    }
  });
}

/**
 * 格式化文件大小
 * @param {number} bytes - 字节数
 * @returns {string} 格式化后的字符串
 */
function formatSize(bytes) {
  if (!bytes || bytes === 0) return "0 B";

  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i];
}

/**
 * 使用系统弹窗（降级方案）
 * @param {Object} updateInfo - 更新信息
 * @returns {boolean} 用户是否确认更新
 */
function useSystemDialog(updateInfo) {
  const { title, contents, version, is_mandatory, pkg_size } = updateInfo;

  // 更现代化的内容格式化
  const versionInfo = version ? `📱 版本：v${version}` : "";
  const sizeInfo = pkg_size ? `📦 大小：${formatSize(pkg_size)}` : "";
  const separator = "━".repeat(20);

  const content = `${contents}\n\n${separator}\n${versionInfo}\n${sizeInfo}`;

  return new Promise((resolve) => {
    // 使用自定义弹窗替代uni.showModal，解决颜色配置无效问题
    const modal = getApp().$modal || this.$modal;
    if (modal && modal.alert) {
      modal
        .alert({
          title: title || "🚀 发现新版本",
          content,
          confirmText: "📥 立即更新",
          cancelText: is_mandatory ? "退出应用" : "⏰ 稍后更新",
          showCancel: !is_mandatory,
        })
        .then((res) => {
          if (!res.confirm && !is_mandatory) {
            // 用户选择稍后更新，不再有任何提示
            console.log("用户选择稍后更新，不再保存待安装提醒");
            uni.removeStorageSync("pendingUpdate");
          }
          resolve(res.confirm);
        })
        .catch(() => {
          console.log("用户取消更新");
          resolve(false);
        });
    } else {
      // 降级使用原生showModal
      uni.showModal({
        title: title || "🚀 发现新版本",
        content,
        showCancel: !is_mandatory,
        confirmText: "📥 立即更新",
        cancelText: is_mandatory ? "退出应用" : "⏰ 稍后更新",
        success: (res) => {
          if (!res.confirm && !is_mandatory) {
            // 用户选择稍后更新，不再有任何提示
            console.log("用户选择稍后更新，不再保存待安装提醒");
            uni.removeStorageSync("pendingUpdate");
          }
          resolve(res.confirm);
        },
        fail: (err) => {
          console.error("系统弹窗显示失败:", err);
          resolve(false); // 弹窗失败时默认不更新
        },
      });
    }
  });
}

/**
 * 显示更新弹窗（自定义UI）
 * @param {Object} updateInfo - 更新信息
 * @returns {Promise<boolean>} 用户是否确认更新
 */
function showUpdateDialog(updateInfo) {
  const {
    title,
    contents,
    version,
    is_mandatory,
    pkg_size,
    url,
    platform,
    type,
  } = updateInfo;

  return new Promise((resolve) => {
    // 存储更新信息到全局，供更新页面使用
    uni.setStorageSync(PACKAGE_INFO_KEY, updateInfo);

    // 跳转到自定义更新页面
    uni.navigateTo({
      url: `/pages/mine/update-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
      success: () => {
        // 监听页面返回事件，获取用户选择
        const eventCallback = (choice) => {
          if (!choice) {
            // 用户选择稍后更新，不再有任何提示
            console.log("用户选择稍后更新，不再保存待安装提醒");
            uni.removeStorageSync("pendingUpdate");
          }
          resolve(choice);
          // 移除事件监听
          uni.$off("update-user-choice", eventCallback);
        };
        uni.$on("update-user-choice", eventCallback);
      },
      fail: (err) => {
        console.error("更新弹框跳转失败", err);
        uni.removeStorageSync(PACKAGE_INFO_KEY);
        // 降级使用系统弹窗
        resolve(useSystemDialog(updateInfo));
      },
    });
  });
}

/**
 * 提示用户安装更新
 * @param {Object} updateInfo - 更新信息
 */
async function promptForInstall(updateInfo) {
  if (!updateInfo) {
    console.error("更新信息无效，无法提示安装");
    return;
  }

  // 不再显示安装提醒，直接安装
  console.log("更新已下载完成，直接开始安装，不再显示安装提醒");
  try {
    await installPackage(updateInfo.filePath, updateInfo, { silent: true });
  } catch (error) {
    console.error("安装失败:", error);
  }
}

/**
 * 静默下载完成后显示安装确认提示
 * @param {string} filePath - 下载文件路径
 * @param {Object} updateInfo - 更新信息
 * @returns {Promise} 用户选择结果
 */
function showSilentInstallConfirm(filePath, updateInfo) {
  return new Promise((resolve, reject) => {
    // 检查是否已经拒绝过此版本的安装
    const declinedVersion = uni.getStorageSync("silent_install_declined");
    if (declinedVersion === updateInfo.versionCode.toString()) {
      console.log("用户已拒绝安装此版本，不再提醒");
      reject(new Error("用户已拒绝安装此版本"));
      return;
    }

    // 显示确认对话框
    uni.showModal({
      title: "新版本下载完成",
      content: `新版本 ${updateInfo.version} 已下载完成，是否立即安装？\n\n${
        updateInfo.content || ""
      }`,
      confirmText: "立即安装",
      cancelText: "稍后安装",
      success: (res) => {
        if (res.confirm) {
          // 用户选择立即安装
          console.log("用户选择立即安装");
          resolve();
        } else if (res.cancel) {
          // 用户选择稍后安装
          console.log("用户选择稍后安装");
          reject(new Error("用户选择稍后安装"));
        }
      },
      fail: (err) => {
        console.error("显示安装确认对话框失败:", err);
        reject(err);
      },
    });
  });
}

/**
 * 检查是否有待安装的更新
 */
function checkPendingUpdate() {
  try {
    const pendingUpdate = uni.getStorageSync("pendingUpdate");
    if (pendingUpdate) {
      console.log("发现待安装的更新");
      // 用户选择"稍后更新"后，不再有任何提示，直接返回false
      console.log("用户之前选择稍后更新，不再显示任何提醒");
      return false;
    }
    return false;
  } catch (error) {
    console.error("检查待安装更新失败:", error);
    return false;
  }
}

/**
 * 下载并安装
 * @param {Object} updateInfo - 更新信息
 * @param {Object} options - 配置选项
 */
async function downloadAndInstall(updateInfo, options = {}) {
  const {
    onProgress,
    autoInstall = false,
    silentDownload = false,
    existingFilePath,
  } = options;
  const { url, type, is_mandatory, title } = updateInfo;

  // 如果提供了已有文件路径，直接使用该文件进行安装
  if (existingFilePath) {
    console.log("使用已有文件进行安装，跳过下载:", existingFilePath);

    // 验证文件是否存在
    try {
      const entry = await new Promise((resolve, reject) => {
        plus.io.resolveLocalFileSystemURL(
          existingFilePath,
          (entry) => resolve(entry),
          (error) => reject(error)
        );
      });

      if (!entry) {
        throw new Error("文件不存在或无法访问");
      }

      console.log("文件验证成功，开始安装...");

      if (autoInstall) {
        // 直接安装
        await installPackage(existingFilePath, updateInfo, {
          silent: silentDownload,
        });
        return {
          downloadComplete: true,
          filePath: existingFilePath,
          versionCode: updateInfo.versionCode,
          versionName: updateInfo.version,
          usedExistingFile: true,
        };
      } else {
        // 询问用户是否安装
        await askForInstall(existingFilePath, updateInfo);
        return {
          downloadComplete: true,
          filePath: existingFilePath,
          versionCode: updateInfo.versionCode,
          versionName: updateInfo.version,
          usedExistingFile: true,
        };
      }
    } catch (error) {
      console.error("使用已有文件失败:", error);
      throw new Error(`使用已有文件安装失败: ${error.message}`);
    }
  }

  // 检查URL是否有效
  if (!url) {
    console.error("下载URL无效:", updateInfo);
    return Promise.reject(new Error("下载URL无效"));
  }

  // URL格式验证（兼容小程序环境）
  try {
    // 简单的URL格式验证，兼容小程序环境
    const urlPattern =
      /^https?:\/\/([\w\-]+\.)+[\w\-]+(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?$/i;
    if (!urlPattern.test(url)) {
      console.error("下载URL格式错误:", url);
      this.$modal.showCustomToast("下载链接格式错误", "error");
      return Promise.reject(new Error("下载URL格式错误"));
    }

    // 检查协议
    if (!url.startsWith("http://") && !url.startsWith("https://")) {
      console.error("下载URL协议不支持:", url);
      this.$modal.showCustomToast("下载链接协议不支持", "error");
      return Promise.reject(new Error("下载URL协议不支持，仅支持HTTP/HTTPS"));
    }
  } catch (e) {
    console.error("下载URL格式错误:", url, e);
    return Promise.reject(new Error("下载URL格式错误"));
  }

  // 网络状态检查
  return new Promise((resolve, reject) => {
    uni.getNetworkType({
      success: (networkRes) => {
        console.log("当前网络类型:", networkRes.networkType);
        if (networkRes.networkType === "none") {
          const modal = getGlobalModal();
          if (modal && modal.showCustomToast) {
            modal.showCustomToast("网络不可用，请检查网络连接", "error");
          }
          reject(new Error("网络不可用，请检查网络连接"));
          return;
        }

        // 网络正常，继续下载
        continueDownload();
      },
      fail: (networkErr) => {
        console.warn("获取网络状态失败:", networkErr);
        // 无法获取网络状态，但仍尝试下载
        continueDownload();
      },
    });

    function continueDownload() {
      console.log("开始下载，URL:", url);

      let downloadTask = null;
      let isDownloading = true;

      // 静默下载模式：不显示下载进度弹窗
      let downloadDialog = null;
      if (!silentDownload) {
        downloadDialog = showDownloadDialog(updateInfo, () => {
          // 用户取消下载
          if (downloadTask && isDownloading) {
            downloadTask.abort();
            isDownloading = false;
            reject(new Error("用户取消下载"));
          }
        });
      }
      console.log("downloadFile开始下载，URL:", url);

      // 增强调试信息
      console.log("下载配置信息:", {
        url: url,
        urlType: typeof url,
        urlLength: url ? url.length : 0,
        hasHeader: !!updateInfo.header,
        timeout: updateInfo.timeout || "默认",
      });

      // 下载前网络状态检查
      if (uni.getNetworkType) {
        uni.getNetworkType({
          success: (networkRes) => {
            console.log("当前网络类型:", networkRes.networkType);
            if (networkRes.networkType === "none") {
              const networkError = {
                errMsg: "downloadFile:fail 网络不可用",
              };
              console.error("网络检查失败: 无网络连接");
              reject(new Error("下载失败: " + networkError.errMsg));
              return;
            }
          },
          fail: (networkErr) => {
            console.warn("获取网络状态失败:", networkErr);
          },
        });
      }

      downloadTask = uni.downloadFile({
        url: url,
        timeout: updateInfo.timeout || 120000, // 增加到120秒超时，大文件下载需要更多时间
        header: updateInfo.header || {
          "User-Agent":
            "Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36",
          Accept: "*/*",
          "Accept-Encoding": "identity",
          Connection: "Keep-Alive",
          "Cache-Control": "no-cache",
        },
        success: (res) => {
          isDownloading = false;
          if (downloadDialog) {
            downloadDialog.close();
          }

          if (res.statusCode === 200) {
            // 下载完成，保存文件路径到updateInfo
            updateInfo.filePath = res.tempFilePath;

            // 直接使用下载的临时文件路径，不再移动到外部存储目录
            let finalFilePath = res.tempFilePath;
            console.log(">>> 使用原始下载路径，跳过文件移动:", finalFilePath);

            // 静默下载成功
            if (silentDownload) {
              console.log("静默下载成功，保存下载信息");
              uni.setStorageSync(
                "last_downloaded_version",
                updateInfo.versionCode.toString()
              );
              uni.setStorageSync("last_downloaded_url", updateInfo.url);
              uni.setStorageSync("last_downloaded_path", finalFilePath);
              console.log(
                ">>> 下载层回传 rawPath：" + JSON.stringify(finalFilePath)
              );
              console.log(
                ">>> 下载层回传 url" + JSON.stringify(updateInfo.url)
              );

              if (autoInstall) {
                console.log("静默下载模式：自动安装已启用");
                setTimeout(() => {
                  installPackage(finalFilePath, updateInfo, {
                    silent: silentDownload,
                  })
                    .then(() => resolve())
                    .catch((err) => reject(err));
                }, 1000);
              } else {
                console.log("静默下载模式：自动安装已禁用，显示安装确认提示");
                // 静默下载完成，显示安装确认提示
                showSilentInstallConfirm(finalFilePath, updateInfo)
                  .then(() => {
                    // 用户选择安装，直接执行安装
                    console.log("用户选择立即安装，开始执行安装");
                    installPackage(finalFilePath, updateInfo, {
                      silent: silentDownload,
                    })
                      .then(() => {
                        resolve({
                          downloadComplete: true,
                          filePath: finalFilePath,
                          versionCode: updateInfo.versionCode,
                          versionName: updateInfo.version,
                          autoInstall: false,
                          userConfirmedInstall: true,
                        });
                      })
                      .catch((err) => {
                        console.error("静默安装失败:", err);
                        reject(err);
                      });
                  })
                  .catch(() => {
                    // 用户选择稍后安装，记录状态避免重复提醒
                    uni.setStorageSync(
                      "silent_install_declined",
                      updateInfo.versionCode.toString()
                    );
                    uni.setStorageSync(
                      "silent_install_declined_time",
                      Date.now().toString()
                    );
                    resolve({
                      downloadComplete: true,
                      filePath: finalFilePath,
                      versionCode: updateInfo.versionCode,
                      versionName: updateInfo.version,
                      autoInstall: false,
                      userConfirmedInstall: false,
                    });
                  });
              }
            } else {
              // 非静默模式：使用移动后的文件路径询问用户是否安装
              askForInstall(finalFilePath, updateInfo)
                .then(() => resolve())
                .catch((err) => reject(err));
            }
          } else {
            const modal = getGlobalModal();
            if (modal && modal.showCustomToast) {
              modal.showCustomToast("下载失败，请重试", "error");
            }
            reject(new Error("下载失败"));
          }
        },
        fail: (err) => {
          isDownloading = false;
          if (downloadDialog) {
            downloadDialog.close();
          }

          // 增强错误日志记录
          console.error("下载失败详细信息:");
          console.error("- URL:", url);
          console.error("- 错误对象:", JSON.stringify(err));
          console.error("- 错误消息:", err.errMsg || "未知错误");
          console.error("- 状态码:", err.statusCode || "无状态码");
          console.error(
            "- 网络状态:",
            uni.getNetworkType ? "需要检查" : "无法获取"
          );

          // 针对downloadFile:fail undefined的特殊处理
          if (err.errMsg === "downloadFile:fail undefined") {
            const modal = getGlobalModal();
            if (modal && modal.showCustomToast) {
              modal.showCustomToast("下载链接异常，请检查网络或重试", "error");
            }
            console.error("=== downloadFile:fail undefined 错误分析 ===");
            console.error("可能原因:");
            console.error("1. URL格式不正确或包含特殊字符");
            console.error("2. 服务器地址不可访问或响应超时");
            console.error("3. 缺少必要的请求头或参数");
            console.error("4. 文件大小超过限制");
            console.error("5. 跨域访问被阻止");
            console.error("建议解决方案:");
            console.error("1. 检查URL是否完整且可访问");
            console.error("2. 确认服务器支持跨域访问");
            console.error("3. 尝试添加合适的请求头");
            console.error("4. 检查网络连接状态");
            console.error("========================================");

            // 尝试备用下载方案
            console.log("尝试备用下载方案...");
            try {
              // 尝试使用XMLHttpRequest作为备用方案
              if (typeof XMLHttpRequest !== "undefined") {
                console.log("使用XMLHttpRequest备用方案");
                const xhr = new XMLHttpRequest();
                xhr.open("GET", url, true);
                xhr.responseType = "blob";
                xhr.timeout = 60000;

                xhr.onload = function () {
                  if (xhr.status === 200) {
                    console.log("XMLHttpRequest下载成功");
                    // 这里需要额外的处理来保存文件
                  } else {
                    console.error(
                      "XMLHttpRequest下载失败，状态码:",
                      xhr.status
                    );
                  }
                };

                xhr.onerror = function () {
                  console.error("XMLHttpRequest网络错误");
                };

                xhr.ontimeout = function () {
                  console.error("XMLHttpRequest超时");
                };

                xhr.send();
              }
            } catch (backupErr) {
              console.error("备用下载方案也失败了:", backupErr);
            }
          }

          // 尝试获取网络状态
          if (uni.getNetworkType) {
            uni.getNetworkType({
              success: (networkRes) => {
                console.error("- 当前网络类型:", networkRes.networkType);
              },
            });
          }

          // 创建更详细的错误信息
          const enhancedError = new Error(
            `下载失败: ${err.errMsg || "未知错误"}` +
              `\nURL: ${url}` +
              `\n建议检查网络连接和服务器状态`
          );
          enhancedError.originalError = err;
          enhancedError.url = url;

          reject(enhancedError);
        },
      });

      // 进度更新
      if (downloadTask) {
        downloadTask.onProgressUpdate((res) => {
          if (downloadDialog) {
            downloadDialog.updateProgress(res.progress);
          }
          onProgress && onProgress(res.progress);
        });
      }
    }
  });
}

/**
 * 检测应用更新
 * @param {Object} options - 配置选项
 * @param {boolean} options.silent - 是否静默检测（不显示加载提示）
 * @param {boolean} options.autoInstall - 是否自动安装（下载完成后自动安装）
 * @param {boolean} options.silentDownload - 是否静默下载（不显示弹窗直接下载）
 * @param {function} options.onProgress - 下载进度回调
 * @param {function} options.onComplete - 完成回调
 * @returns {Promise<Object>} 返回检测结果
 */
async function checkAppUpdate(options = {}) {
  const {
    silent = false,
    autoInstall = false,
    silentDownload = false,
    onProgress,
    onComplete,
  } = options;

  try {
    const { data } = await AppVersionApi.getAppVersionPage({
      pageNo: 1,
      pageSize: 1,
    });
    console.log("获取到的版本信息14:", data);
    const latest = data.list[0];
    if (!latest) {
      throw new Error("未获取到版本信息");
    }

    // 获取当前版本号
    const manifest = require("@/manifest.json");
    const currentVersion = parseInt(manifest.versionCode) || 1;

    // 版本比较（遵循开发说明书4.4）
    const hasUpdate = compareVersions(latest.versionCode, currentVersion) > 0;

    // 没有更新
    if (!hasUpdate) {
      if (!silent) {
        const modal = getGlobalModal();
        if (modal && modal.showCustomToast) {
          modal.showCustomToast("当前已是最新版本", "success");
        }
      }
      return { hasUpdate: false, message: "当前已是最新版本" };
    }

    // 有更新，构建更新信息对象
    // 获取当前应用访问地址
    const currentBaseUrl = config.getDynamicBaseUrl();
    console.log("当前应用访问地址:", currentBaseUrl);
    // 输出所有版本信息字段，确认patchUrl是否存在
    // console.log("所有版本信息:", latest);
    // 构建更新信息对象
    const updateInfo = {
      versionCode: latest.versionCode,
      version: latest.versionName,
      title: latest.title || "发现新版本",
      contents: latest.releaseNotes,
      // 根据当前访问地址选择下载路径：办公环境(http://10.76.83.96:48000)使用patchUrl，其他环境使用pkgUrl
      url:
        currentBaseUrl === "http://10.76.83.96:48000"
          ? latest.patchUrl
          : latest.pkgUrl,
      pkg_size: latest.pkgSize * 1024 * 1024, // MB转字节
      is_mandatory: false, // 前端忽略后台isForce，始终双按钮
      type: "app", // 默认为整包更新
    };
    console.log("构建的更新信息对象:", updateInfo);

    // 静默下载模式：不显示弹窗，直接开始下载
    if (silentDownload) {
      console.log("静默下载模式：开始下载更新包");
      console.log("下载URL:", updateInfo.url);

      // 检查URL是否有效
      if (!updateInfo.url) {
        console.error("下载URL无效:", updateInfo);
        throw new Error("下载URL无效");
      }

      // 不等待下载完成，立即返回结果
      downloadAndInstall(updateInfo, {
        onProgress,
        autoInstall: false,
        silentDownload: true,
      })
        .then((result) => {
          console.log("静默下载完成");
          // 下载完成后调用回调
          onComplete &&
            onComplete({
              hasUpdate: true,
              silentDownload: true,
              downloadComplete: true,
              filePath: result?.filePath,
              versionCode: result?.versionCode,
              versionName: result?.versionName,
            });

          // 静默下载完成后，提示用户安装
          console.log("静默下载完成，准备提示用户安装");

          // 显示安装提示，让用户选择是否立即安装
          uni.showModal({
            title: "下载完成",
            content: "新版本下载完成，是否立即安装？",
            showCancel: true,
            confirmText: "立即安装",
            cancelText: "稍后安装",
            success: (res) => {
              if (res.confirm) {
                console.log("用户选择立即安装");
                // 用户选择立即安装，执行安装
                if (result?.filePath) {
                  installPackage(result.filePath, updateInfo).catch((error) => {
                    console.error("静默下载后安装失败:", error);
                    uni.showToast({
                      title: "安装失败，请手动安装",
                      icon: "none",
                      duration: 3000,
                    });
                  });
                }
              } else {
                console.log("用户选择稍后安装");
                // 用户选择稍后安装，保存待安装信息
                const pendingUpdate = {
                  filePath: result?.filePath,
                  versionCode: result?.versionCode,
                  versionName: result?.versionName,
                  updateInfo: updateInfo,
                  downloadTime: new Date().getTime(),
                };
                uni.setStorageSync("pendingUpdate", pendingUpdate);

                uni.showToast({
                  title: "已保存更新，可在我页面手动安装",
                  icon: "none",
                  duration: 3000,
                });
              }
            },
          });
        })
        .catch((error) => {
          console.error("静默下载失败:", error);
          console.error("静默下载失败详细信息:");
          console.error("- 错误消息:", error.message || "未知错误");
          console.error("- 错误对象:", error);
          console.error("- 下载URL:", updateInfo.url || "无URL");

          // 检查是否是网络相关错误
          if (error.message && error.message.includes("downloadFile:fail")) {
            console.error("- 疑似网络连接问题，建议检查:");
            console.error("  1. 服务器地址是否可访问");
            console.error("  2. 网络连接是否正常");
          }

          // 下载失败后调用回调
          onComplete &&
            onComplete({
              hasUpdate: true,
              silentDownload: false,
              error: error.message || "下载失败",
              downloadUrl: updateInfo.url,
            });
        });

      // 注意：这里不能访问result，因为downloadAndInstall是异步的
      // 返回基本结构，详细信息通过onComplete回调传递
      return {
        hasUpdate: true,
        userConfirm: true,
        silentDownload: true,
        downloadComplete: false, // 下载刚开始，还未完成
        message: "静默下载已启动",
      };
    }

    // 显示更新弹窗
    const userConfirm = await showUpdateDialog(updateInfo);

    if (userConfirm) {
      // 用户选择"立即更新"，设置autoInstall为true，下载完成后直接安装
      await downloadAndInstall(updateInfo, { onProgress, autoInstall: true });
    } else {
      // 用户选择"稍后更新"，清除任何待安装提醒
      uni.removeStorageSync("pendingUpdate");
    }

    return { hasUpdate: true, userConfirm };
  } catch (error) {
    console.error("版本检测失败:", error);

    if (!silent) {
      const modal = getGlobalModal();
      if (modal && modal.showCustomToast) {
        modal.showCustomToast(error.message || "网络异常，请稍后重试", "error");
      }
    }

    throw error;
  } finally {
    if (!silent) {
      uni.hideLoading();
    }
  }
}

// #endif

// #ifndef APP-PLUS
// 非APP环境下的方法实现
function checkAppUpdate() {
  return Promise.resolve({ hasUpdate: false });
}

function downloadAndInstall() {
  return Promise.resolve({ success: false, error: "非APP环境" });
}

function promptForInstall() {
  return Promise.resolve({ success: false, error: "非APP环境" });
}

function checkPendingUpdate() {
  return Promise.resolve({ hasUpdate: false });
}

function reqInstallPermission() {
  return Promise.resolve({ granted: false });
}
// #endif

// 统一导出
export default {
  checkAppUpdate,
  downloadAndInstall,
  promptForInstall,
  checkPendingUpdate,
  reqInstallPermission,
};
